package crudfx.navigation;
import crudfx.interop.*;
import crudfx.navigation.*;
import crudfx.util.*;
import crudfx.util.resources.*;
import javax.swing.*;
import java.awt.event.*;
import java.awt.*;
import javax.swing.border.*;
import javax.swing.tree.*;
import crudfx.field.*;
import crudfx.data.*;
import crudfx.util.resources.*;
import javax.swing.event.*;
import java.util.*;
/**
 * @profile desktop
 * @author Sergey Surikov
 */
class StandardTreeNode extends DefaultMutableTreeNode{
    public var content:TreeItem;
    }

/**
 * @profile desktop
 * @author Sergey Surikov
 */
class StandardTreeCellEditor extends TreeCellEditor{
    var editor:DefaultTreeCellEditor;
    var renderer:StandardTreeCellRenderer;
    override function getTreeCellEditorComponent(tree:JTree,value:Object
                                                ,selected:Boolean,expanded:Boolean
                                                ,leaf:Boolean,row:Integer
                                                ):Component{
        //return editor.getTreeCellEditorComponent(tree,value,selected,expanded,leaf,row);
        return renderer.getTreeCellRendererComponent(tree,value,selected,expanded,leaf,row,true);
        }
    override function getCellEditorValue():Object{return editor.getCellEditorValue();}
    override function isCellEditable(e:EventObject):Boolean{return editor.isCellEditable(e);}
    override function shouldSelectCell(e:EventObject):Boolean{return editor.shouldSelectCell(e);;}
    override function stopCellEditing():Boolean{return editor.stopCellEditing();}
    override function cancelCellEditing():Void{editor.cancelCellEditing();}
    override function addCellEditorListener(e:CellEditorListener):Void{editor.addCellEditorListener(e);}
    override function removeCellEditorListener(e:CellEditorListener):Void{editor.removeCellEditorListener(e);}
}
/**
 * @profile desktop
 * @author Sergey Surikov
 */
class StandardTreeCellRenderer extends DefaultTreeCellRenderer{    
    override function getTreeCellRendererComponent(tree:JTree,value:Object
                                                ,selected:Boolean,expanded:Boolean
                                                ,leaf:Boolean,row:Integer
                                                ,hasFocus:Boolean):Component{
        var node:StandardTreeNode=extract(value);
        if(node!=null){
            var component:Component=node.content.getCellComponent(tree
                                    ,value,selected,expanded,leaf,row,hasFocus);
            //var j=component as JComponent;
            //j.setOpaque(false);
            //j.setBackground(new java.awt.Color(100,0,0));
            //println(j);
            return component;
            }
        else{
            return super.getTreeCellRendererComponent(tree,value
                                                ,selected,expanded,leaf,row
                                                ,hasFocus);
            }
        }
    }
/**
 * @profile desktop
 * @author Sergey Surikov
 */
public class Tree extends UIComponent{
    var jTree:JTree;
    var jScrollPane:JScrollPane;
    var model:DefaultTreeModel;
    var root:DefaultMutableTreeNode;
    var renderer:StandardTreeCellRenderer;
    public var content:TreeItem[];
    init{
        jScrollPane=new JScrollPane();
        jTree=JTree{
            override function getToolTipText(e:MouseEvent):String{
                var treePath:TreePath=jTree.getClosestPathForLocation(e.getX(), e.getY());
                var node:StandardTreeNode=extract(treePath.getLastPathComponent());
                if(node!=null){
                    return node.content.tooltip;
                    }
                return "";
                }
            };
        renderer=new StandardTreeCellRenderer();
        jTree.setCellRenderer(renderer);
        var editorHelper:DefaultTreeCellEditor=new DefaultTreeCellEditor(jTree,renderer);
        var editor:StandardTreeCellEditor=StandardTreeCellEditor{
            editor:editorHelper
            renderer:renderer
            };
        jTree.setCellEditor(editor);
        /*root=new DefaultMutableTreeNode();
        model=new DefaultTreeModel(root);
        jTree.setModel(model);*/
        var border=new EmptyBorder(4,4,4,4);
        jTree.setBorder(border);
        jTree.setRootVisible(false);
        jTree.setShowsRootHandles(true);
        jTree.setToggleClickCount(1);
        jScrollPane.getViewport().add(jTree);
        jScrollPane.setOpaque(false);
        jScrollPane.getViewport().setOpaque(false);
        jScrollPane.setBorder(new EmptyBorder(0,0,0,0));
        jTree.setOpaque(false);
        reset();
        var treeSelectionListener:TreeSelectionListener=TreeSelectionListener{
            override public function valueChanged(e:TreeSelectionEvent) :Void{
                var node:StandardTreeNode=extract(jTree.getLastSelectedPathComponent());
                if(node!=null){
                        if(node.content.onSelect()){
                            jTree.startEditingAtPath(jTree.getSelectionPath());
                            }
                    }
                }
            };
        jTree.addTreeSelectionListener(treeSelectionListener);
        ToolTipManager.sharedInstance().registerComponent(jTree);
        var mouseAdapter:MouseAdapter=MouseAdapter{
            override public function mousePressed(e:MouseEvent):Void{checkPopup(e);}
            override public function mouseReleased(e:MouseEvent):Void{checkPopup(e);}};
        jTree.addMouseListener(mouseAdapter);
        jTree.setEditable(true);
        jTree.setRowHeight(0);
        }
    function checkPopup(e:MouseEvent){
        if(e.isPopupTrigger()){
            var treePath:TreePath=jTree.getClosestPathForLocation(e.getX(), e.getY());
            if (not jTree.isPathSelected(treePath)){
                jTree.setSelectionPath(treePath);
                }
            var relative:Point = e.getPoint();
            var node:StandardTreeNode=extract(jTree.getLastSelectedPathComponent());
            if(node!=null){
                if(node.content.popup==null){
                    node.content.popup=PopUp{
                        items:[
                            MenuLink{
                                text:"Find"
                                }
                            ]
                        }
                    }
                }
            node.content.popup.show(this,e.getX(),e.getY());
            }
        }
    function extract(value:Object):StandardTreeNode{
        var node:StandardTreeNode=null;
        try{
            var c:String=value.getClass().toString();
            if(c.equals("class crudfx.navigation.Tree$StandardTreeNode")){
                node=value as StandardTreeNode;
                }
        }catch(x){
            x.printStackTrace();
            }
        return node;
        }
    public function add(parent:DefaultMutableTreeNode,node:TreeItem):DefaultMutableTreeNode{
        parent.add(StandardTreeNode{
                content:node
                }
            );
        return parent.getLastChild() as DefaultMutableTreeNode;
        }
    public function reset(){
        //println(root.getChildCount());
        //root.removeAllChildren();
        root=new DefaultMutableTreeNode();
        for(t:TreeItem in content)t.add(this, root);
        model=new DefaultTreeModel(root);
        jTree.setModel(model);        
        //jTree.revalidate();
        }
    override public function getJComponent():JComponent{
        return jScrollPane;
        }
    override public function highlight(s:String):Boolean{
        return false;
        }
    override public function gather():DataTree{
        var me:DataTree=DataTree{ name:"Tree" };
        //me.node("text").asString("").value=text;
        return me;
        }
    }
